package cn.springboot.common.http;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;

/**
 * HttpCilent工具类
 *
 * @author junrui.wang
 * @create 2016/10/19
 */
public class HttpClientUtils {
    private final static Logger slf4jLogger = LoggerFactory.getLogger(HttpClientUtils.class);

    /**
     * HttpGet请求数据
     * @param url
     * @param valueType
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> T httpGetRequest(String url, Class<T> valueType) throws Exception {
        slf4jLogger.info("httpGetRequest() url=" + url);
        T result = null;
        HttpGet httpGet = null;
        try{
            httpGet = new HttpGet(url);
            httpGet.setHeader("Accept", "application/json");
            httpGet.setHeader("Content-Type", "application/json");
            HttpResponse httpResponse = HttpClientPool.httpClient.execute(httpGet);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                try {
                    InputStream inputStream = (InputStream) httpResponse.getEntity().getContent();
                    ObjectMapper mapper = new ObjectMapper();
                    result = mapper.readValue(inputStream, valueType);
                    inputStream.close();
                } catch (Exception e) {
                    result = valueType.newInstance();
                }
            } else{
                Header code = httpResponse.getFirstHeader("x-aqua-error-code");
                Header message = httpResponse.getFirstHeader("x-aqua-error-message");
                String codeStr = "";
                String messageStr = "";
                if(code != null){
                    codeStr = code.getValue();
                }
                if(message != null){
                    messageStr = message.getValue();
                }
                slf4jLogger.error("httpGetRequest() statusCode:" + httpResponse.getStatusLine().getStatusCode()
                        + ",errorCode:" + codeStr + ",errorMessage:" + messageStr);
                throw new Exception(codeStr + "/" + messageStr + "/" + httpResponse.getStatusLine().getStatusCode());
            }
            if (result == null) {
                slf4jLogger.error("httpGetRequest() error : result is null");
            }
        } catch (Exception e){
            slf4jLogger.error("httpGetRequest() error : ", e);
            throw new Exception(e);
        } finally {
            httpGet.releaseConnection();
        }
        return result;
    }

    public static <T> T httpPostRequest(String url, String body, Class<T> valueType) throws Exception {
        slf4jLogger.info("httpPostRequest() url=" + url + ",body=" + body);
        T result = null;
        HttpPost httpPost = null;
        try{
            httpPost = new HttpPost(url);
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setEntity(new StringEntity(body,"UTF-8"));
            HttpResponse httpResponse = HttpClientPool.httpClient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                try {
                    InputStream inputStream = (InputStream) httpResponse.getEntity().getContent();
                    ObjectMapper mapper = new ObjectMapper();
                    result = mapper.readValue(inputStream, valueType);
                    inputStream.close();
                } catch (Exception e) {
                    result = valueType.newInstance();
                }
            } else{
                Header code = httpResponse.getFirstHeader("x-aqua-error-code");
                Header message = httpResponse.getFirstHeader("x-aqua-error-message");
                String codeStr = "";
                String messageStr = "";
                if(code != null){
                    codeStr = code.getValue();
                }
                if(message != null){
                    messageStr = message.getValue();
                }
                slf4jLogger.error("httpGetRequest() statusCode:" + httpResponse.getStatusLine().getStatusCode()
                        + ",errorCode:" + codeStr + ",errorMessage:" + messageStr);
                throw new Exception(codeStr + "/" + messageStr + "/" + httpResponse.getStatusLine().getStatusCode());
            }
            if (result == null) {
                slf4jLogger.error("httpPostRequest() error : result is null");
            }
        } catch (Exception e){
            slf4jLogger.error("httpPostRequest() error : ", e);
            throw new Exception(e);
        } finally {
            httpPost.releaseConnection();
        }
        return result;
    }

    public static <T> T httpPutRequest(String url, String body, Class<T> valueType) throws Exception {
        slf4jLogger.info("httpPutRequest() url=" + url + ",body=" + body);
        T result = null;
        HttpPut httpPut = null;
        try{
            httpPut = new HttpPut(url);
            httpPut.setHeader("Accept", "application/json");
            httpPut.setHeader("Content-Type", "application/json");
            httpPut.setEntity(new StringEntity(body,"UTF-8"));
            HttpResponse httpResponse = HttpClientPool.httpClient.execute(httpPut);
            if (httpResponse.getStatusLine().getStatusCode() == 200 || httpResponse.getStatusLine().getStatusCode() == 201) {
                try {
                    InputStream inputStream = (InputStream) httpResponse.getEntity().getContent();
                    ObjectMapper mapper = new ObjectMapper();
                    result = mapper.readValue(inputStream, valueType);
                    inputStream.close();
                } catch (Exception e) {
                    result = valueType.newInstance();
                }
            } else{
                Header code = httpResponse.getFirstHeader("x-aqua-error-code");
                Header message = httpResponse.getFirstHeader("x-aqua-error-message");
                String codeStr = "";
                String messageStr = "";
                if(code != null){
                    codeStr = code.getValue();
                }
                if(message != null){
                    messageStr = message.getValue();
                }
                slf4jLogger.error("httpGetRequest() statusCode:" + httpResponse.getStatusLine().getStatusCode()
                        + ",errorCode:" + codeStr + ",errorMessage:" + messageStr);
                throw new Exception(codeStr + "/" + messageStr + "/" + httpResponse.getStatusLine().getStatusCode());
            }
            if (result == null) {
                slf4jLogger.error("httpPutRequest() error : result is null");
            }
        } catch (Exception e){
            slf4jLogger.error("httpPutRequest() error : ", e);
            throw new Exception(e);
        } finally {
            httpPut.releaseConnection();
        }
        return result;
    }

    public static boolean httpDeleteRequest(String url) throws Exception {
        slf4jLogger.info("httpDeleteRequest() url=" + url);
        HttpDelete httpDelete = null;
        try {
            httpDelete = new HttpDelete(url);
            httpDelete.setHeader("Accept", "application/json");
            httpDelete.setHeader("Content-Type", "application/json");
            HttpResponse httpResponse = HttpClientPool.httpClient.execute(httpDelete);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                slf4jLogger.info("httpDeleteRequest() success");
                return true;
            } else {
                Header code = httpResponse.getFirstHeader("x-aqua-error-code");
                Header message = httpResponse.getFirstHeader("x-aqua-error-message");
                String codeStr = "";
                String messageStr = "";
                if(code != null){
                    codeStr = code.getValue();
                }
                if(message != null){
                    messageStr = message.getValue();
                }
                slf4jLogger.error("httpGetRequest() statusCode:" + httpResponse.getStatusLine().getStatusCode()
                        + ",errorCode:" + codeStr + ",errorMessage:" + messageStr);
                throw new Exception(codeStr + "/" + messageStr + "/" + httpResponse.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            slf4jLogger.error("httpPutRequest() error : ", e);
            throw new Exception(e);
        } finally {
            httpDelete.releaseConnection();
        }
    }
}
